
-- mysql封装 跟具体业务无关

local assert     = assert
local require    = require    
local bit        = bit
local coroutine  = coroutine
local debug      = debug
local io         = io
local pairs      = pairs
local ipairs     = ipairs
local math       = math
local os         = os
local print      = print
local pcall      = pcall
local xpcall     = xpcall
local rawget     = rawget
local rawset     = rawset
local select     = select
local string     = string
local table      = table
local tonumber   = tonumber
local tostring	 = tostring
local error      = error
local type       = type
local unpack     = unpack
local setmetatable = setmetatable
local getmetatable = getmetatable
local ngx = ngx

local log       = require("modules.commhm.log");
local ns_time   = require("modules.commhm.time");
local uu        = require("modules.commhm.utils");


-- MYSQL MGR类
local _M = { _VERSION = '0.12.1' }
local mt = { __index = _M }

--[[
{
	where={
		uin=111,
		wid=222,
	},

	values={
		country='111',
		label=222,
	},
}
--]]



function _M.new(self, table_name_, data_ )
	log.debug( log.fast() and "call mysqlMgr:new" );
	local ins_ = {
		table_name = table_name_,     ---t_xxxx
		data       = data_,
	};
    return setmetatable(ins_, mt);
end


---获得select语句
_M.getSelectSql = function(self, fields_string_, post_fix_ )
	if  not fields_string_ then
		fields_string_ = "*"
	end

	local mysql_ = "select " ..  fields_string_ ..  " from " .. self.table_name
	if  self.data.where or self.data.where_compare then
		mysql_ = mysql_ .. _M.getWhereByTable( self.data.where, self.data.where_compare )
	end

	if  post_fix_ then
		mysql_ = mysql_ .. " " .. post_fix_
	end

	log.debug( log.fast() and "getSelectSql=" .. mysql_ )
	return mysql_
end

---获得count语句
_M.getCountSql = function(self, limit_)
	local mysql_ = "select 1 from " .. self.table_name
	if  self.data.where or self.data.where_compare then
		mysql_ = mysql_ .. _M.getWhereByTable( self.data.where, self.data.where_compare )
	end

    mysql_ = "select count(1) as cc from (" .. mysql_ .. " " .. limit_ .. ") a"

	log.debug( log.fast() and "getCountSql=" .. mysql_ )
	return mysql_
end


---获得insert语句
_M.getInsertSql = function(self)
	local mysql_ = "insert into " .. self.table_name

	local fields_ = " ("
	local values_ = " ("

	local seq_ = 0
	for k, v in pairs( self.data.values ) do
		if  seq_ > 0 then
			fields_ = fields_ .. ","
			values_ = values_ .. ","
		end
		fields_ = fields_ .. k
		values_ = values_ .. _M.getFieldString( v )
		seq_ = seq_ + 1
	end

	fields_ = fields_ .. ")"
	values_ = values_ .. ")"

	mysql_ = mysql_ .. fields_ .. " values " .. values_

	log.debug( log.fast() and "getInsertSql=" .. mysql_ )
	return mysql_
end

_M.getReplaceSql = function(self)
	local mysql_ = "replace into " .. self.table_name

	local fields_ = " ("
	local values_ = " ("

	local seq_ = 0
	for k, v in pairs( self.data.values ) do
		if  seq_ > 0 then
			fields_ = fields_ .. ","
			values_ = values_ .. ","
		end
		fields_ = fields_ .. k
		values_ = values_ .. _M.getFieldString( v )
		seq_ = seq_ + 1
	end

	fields_ = fields_ .. ")"
	values_ = values_ .. ")"

	mysql_ = mysql_ .. fields_ .. " values " .. values_

	log.debug( log.fast() and "getInsertSql=" .. mysql_ )
	return mysql_
end

---获得update语句
_M.getUpdateSql = function(self, post_fix_)
	---update操作必须有where字段
	if  not ( uu.tableNotEmpty( self.data.where ) or uu.tableNotEmpty(self.data.where_compare) ) then
		log.error( "mysql_task find empty where and where_compare:" .. uu.table2json(self.data))
		assert(nil)
		return ""
	end

	local mysql_ = "update " .. self.table_name .. " set "
	if  self.data.values then
		mysql_ = mysql_ .. _M.getUpdateSetByTable( self.data.values )
	end

	if  self.data.where or self.data.where_compare then
		mysql_ = mysql_ .. _M.getWhereByTable( self.data.where, self.data.where_compare )
	end

	if  post_fix_ then
		mysql_ = mysql_ .. " " .. post_fix_
	end

	log.debug("getUpdateSql=" .. mysql_ )
	return mysql_
end


---获得delete语句
_M.getDeleteSql = function(self)

	---delete操作必须有where或者where_compare
	if  not ( uu.tableNotEmpty( self.data.where ) or uu.tableNotEmpty(self.data.where_compare) ) then
		log.error( "mysql_task find empty where and where_compare" )
		assert(nil)
		return ""
	end

	local mysql_ = "delete from " .. self.table_name .. _M.getWhereByTable( self.data.where, self.data.where_compare )
	log.debug( log.fast() and "getInsertSql=" .. mysql_ )
	return mysql_
end


--------------------------utils---------
_M.getFieldString = function( v )
	if  type(v) == 'number' then
		return v
	elseif type(v) == 'string' then
		return "'" .. v .. "'"
	else
		log.error( "mysql_task, getFieldString type error=" .. type(v) )
		assert(nil)
	end
end


----input   t_={ a=1, b=2 }   t_compare_={ "a>1", "(b<2 or b>5)"  }
----return  where a=1 and b=2
_M.getWhereByTable = function( t_, t_compare_ )
	local ret_ = ""
	local seq_ = 0

	if  t_ then
		for k, v in pairs( t_ ) do
			if  seq_ > 0 then
				ret_ = ret_ .. " and "
			else
				ret_ = " where "
			end
			ret_ = ret_ .. k .. "=" .. _M.getFieldString( v )
			seq_ = seq_ + 1
		end
	end

	if  t_compare_ then
		for k, v in pairs( t_compare_ ) do
			if  seq_ > 0 then
				ret_ = ret_ .. " and "
			else
				ret_ = " where "
			end
			ret_ = ret_ .. v
			seq_ = seq_ + 1
		end
	end


	return ret_
end


----input   { a=1, b=2 }
----return  a=1, b=2
_M.getUpdateSetByTable = function( t_ )
	local ret_ = ""
	local seq_ = 0
	for k, v in pairs( t_ ) do
		if  seq_ > 0 then
			ret_ = ret_ .. ", "
		end
		ret_ = ret_ .. k .. "=" .. _M.getFieldString( v )
		seq_ = seq_ + 1
	end
	return ret_
end




return _M;
